home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-10-04 | 38.5 KB | 1,116 lines |
-
- package sub_arctic.constraints;
-
- import sub_arctic.lib.interactor;
- import sub_arctic.lib.interactor_consts;
- import sub_arctic.lib.manager;
- import sub_arctic.lib.sub_arctic_error;
-
- import java.util.Vector;
-
- /**
- * Class that provides the implementation for standard lightweight constraints.
- * This class understand how to encode and decode an integer encoding of
- * a constraint, and use that to perform operations such as evaluate the
- * constraint, determine if it depends upon a particular value, produce a
- * human readable rendition of the constraint, etc. <p>
- *
- * There should only be one instance of this class created:
- * std_constraint_impl.the_impl(). This should be shared by all constraints.
- * encoded in standard form.<p>
- *
- * In order to organize this class into more manageable units, it is
- * actually implemented with four helper classes, one for each of the
- * possible numbers of operands to the constraint. These are: op0_impl,
- * op1_impl, op2_impl, and op3_impl. See those classes for full encoding
- * details.<p>
- *
- * @see sub_arctic.constraints.op0_impl
- * @see sub_arctic.constraints.op1_impl
- * @see sub_arctic.constraints.op2_impl
- * @see sub_arctic.constraints.op3_impl
- * @author Scott Hudson
- */
- public class std_constraint_impl
- implements constraint_impl, std_encoding_consts {
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * Protected constructor -- no instances of this class should be created
- * outside the one stored statically with the class (the_impl).
- */
- protected std_constraint_impl() { }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /** The one and only instance of this class. This instance should be shared
- * by all constraints encoded in standard form. */
- protected static final std_constraint_impl _the_impl
- = new std_constraint_impl();
-
- /** The one and only instance of this class. This instance should be shared
- * by all constraints encoded in standard form. */
- public static std_constraint_impl the_impl() {return _the_impl;}
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * Determine which kind of constraint (how many operands) the given
- * encoding has. <p>
- *
- * @param int enc the encoding for the constraint.
- * @return int the number of operands in the encoded constraint.
- */
- public int num_ops(int enc)
- {
- int low5, mid5;
-
- /* pull off the low order 5 bits */
- low5 = enc & 0x1f;
-
- /* 0 => 3 op */
- if (low5 == 0) return 3;
-
- /* 1 => 0 or 1 */
- if (low5 == 1)
- {
- /* pull off next 5 bits */
- mid5 = enc & 0x1e0;
-
- /* 0 => 0 op, anything else is a 1 op */
- if (mid5 == 0) return 0; else return 1;
- }
- /* anything else in lower 5 bits => 2 op */
- return 2;
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * Create a human readable string corresponding to the constant contained in
- * the given encoded constraint. <p>
- *
- * @param int enc the constraint encoding
- * @return String a string depicting the designator
- */
- public String const_str(int enc)
- {
- switch(num_ops(enc))
- {
- case 0: return Integer.toString(op0_impl.const_val(enc));
- case 1: return Integer.toString(op1_impl.const_val(enc));
- case 2: return Integer.toString(op2_impl.const_val(enc));
- case 3: return Integer.toString(op3_impl.const_val(enc));
- default: return "ERROR";
- }
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * Create a human readable string corresponding to an object/part designator.
- *
- * @param int enc the designator encoding
- * @param int orient the orientation of the encoding (HORIZONTAL or VERTICAL)
- * @return String a string depicting the designator
- */
- public String obj_part_str(int enc, int orient)
- {
- int obj_code = (enc >> OBJCODE_SHIFT) & OBJCODE_MASK;
- int prt_code = (enc >> PARTCODE_SHIFT) & PARTCODE_MASK;
-
- if (orient == HORIZONTAL)
- return OBJCODE_strings[obj_code] + "." + PARTCODE_strings_h[prt_code];
- else
- return OBJCODE_strings[obj_code] + "." + PARTCODE_strings_v[prt_code];
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * Create a human readable string corresponding to the op_code from the
- * given constraint encoding.
- *
- * @param int enc the constraint encoding
- * @return String a human readable string with the extracted op code
- */
- public String opcode_str(int enc)
- {
- switch(num_ops(enc))
- {
- case 0: return OP0_strings[op0_impl.op_code(enc)-OP0_MIN];
- case 1: return OP1_strings[op1_impl.op_code(enc)-OP1_MIN];
- case 2: return OP2_strings[op2_impl.op_code(enc)-OP2_MIN];
- case 3: return OP3_strings[op3_impl.op_code(enc)-OP3_MIN];
- default: return "ERROR";
- }
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * Create a human readable string corresponding to the operands of the
- * given constraint encoding.
- *
- * @param int enc the constraint encoding
- * @param int orient the orientation of the encoding (HORIZONTAL or VERTICAL)
- * @return String a human readable string for the operands
- */
- public String operand_str(int enc, int orient)
- {
- switch(num_ops(enc))
- {
- case 0: return "(" + op0_impl.const_val(enc) + ")";
- case 1: return "(" + obj_part_str(op1_impl.op1(enc), orient) + "," +
- op1_impl.const_val(enc) + ")";
- case 2: return "(" + obj_part_str(op2_impl.op1(enc), orient) + "," +
- obj_part_str(op2_impl.op2(enc), orient) + "," +
- op2_impl.const_val(enc) + ")";
- case 3: return "(" + obj_part_str(op3_impl.op1(enc), orient) + "," +
- obj_part_str(op3_impl.op2(enc), orient) + "," +
- obj_part_str(op3_impl.op3(enc), orient) + "," +
- op3_impl.const_val(enc) + ")";
- default: return "(ERROR)";
- }
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * Create a human readable string corresponding to the given constraint
- * encoding.
- *
- * @param int enc the constraint encoding
- * @param int orient the orientation of the encoding (HORIZONTAL or VERTICAL)
- * @return String a human readable string for the constraint
- */
- public String str_for(int enc, int orient)
- {
- return opcode_str(enc) + operand_str(enc, orient);
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * Create a terse human readable string corresponding to an object/part
- * designator.
- *
- * @param int enc the designator encoding
- * @param int orient the orientation of the encoding (HORIZONTAL or VERTICAL)
- * @return String a string depicting the designator
- */
- public String obj_part_tag(int enc, int orient)
- {
- int obj_code = (enc >> OBJCODE_SHIFT) & OBJCODE_MASK;
- int prt_code = (enc >> PARTCODE_SHIFT) & PARTCODE_MASK;
-
- if (orient == HORIZONTAL)
- return OBJCODE_tags[obj_code] + "." + PARTCODE_tags_h[prt_code];
- else
- return OBJCODE_tags[obj_code] + "." + PARTCODE_tags_v[prt_code];
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * Create a terse human readable string corresponding to the op_code from the
- * given constraint encoding.
- *
- * @param int enc the constraint encoding
- * @return String a human readable string with the extracted op code
- */
- public String opcode_tag(int enc)
- {
- switch(num_ops(enc))
- {
- case 0: return OP0_tags[op0_impl.op_code(enc)-OP0_MIN];
- case 1: return OP1_tags[op1_impl.op_code(enc)-OP1_MIN];
- case 2: return OP2_tags[op2_impl.op_code(enc)-OP2_MIN];
- case 3: return OP3_tags[op3_impl.op_code(enc)-OP3_MIN];
- default: return "ERROR";
- }
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * Create a terse human readable string corresponding to the operands of the
- * given constraint encoding.
- *
- * @param int enc the constraint encoding
- * @param int orient the orientation of the encoding (HORIZONTAL or VERTICAL)
- * @return String a human readable string for the operands
- */
- public String operand_tag(int enc, int orient)
- {
- switch(num_ops(enc))
- {
- case 0: return "(" + op0_impl.const_val(enc) + ")";
- case 1: return "(" + obj_part_tag(op1_impl.op1(enc),orient) + "," +
- op1_impl.const_val(enc) + ")";
- case 2: return "(" + obj_part_tag(op2_impl.op1(enc),orient) + "," +
- obj_part_tag(op2_impl.op2(enc),orient) + "," +
- op2_impl.const_val(enc) + ")";
- case 3: return "(" + obj_part_tag(op3_impl.op1(enc),orient) + "," +
- obj_part_tag(op3_impl.op2(enc),orient) + "," +
- obj_part_tag(op3_impl.op3(enc),orient) + "," +
- op3_impl.const_val(enc) + ")";
- default: return "(ERROR)";
- }
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * Create a terse human readable string corresponding to the given constraint
- * encoding.
- *
- * @param int enc the constraint encoding
- * @param int orient the orientation of the encoding (HORIZONTAL or VERTICAL)
- * @return String a human readable string for the constraint
- */
- public String tag_for(int enc, int orient)
- {
- return opcode_tag(enc) + operand_tag(enc, orient);
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /* Part constants copied over from interactor_consts for convenience. */
- protected static final int X = interactor_consts.X;
- protected static final int Y = interactor_consts.Y;
- protected static final int W = interactor_consts.W;
- protected static final int H = interactor_consts.H;
- protected static final int VISIBLE = interactor_consts.VISIBLE;
- protected static final int ENABLED = interactor_consts.ENABLED;
- protected static final int PART_A = interactor_consts.PART_A;
- protected static final int PART_B = interactor_consts.PART_B;
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /** Fetch a particular value on behalf of a given part in a particular
- * orientation. This is used for non-parent values only. No coord transform
- * is applied to the value before it is returned<p>
- *
- * @see std_constraint_impl#get_parent_value
- * @param interactor from_obj object we are getting the value from
- * @param int from_part component of that object we want
- * @param int orient orientation (should be HORIZONTAL or VERTICAL)
- * @returns int the value requested (brought up-to-date if needed)
- */
- protected int get_value(
- interactor from_obj,
- int from_part,
- int orient)
- {
- /* horizontal? */
- if (orient == HORIZONTAL)
- switch (from_part)
- {
- case PARTCODE_XY:
- return from_obj.get_part(X);
- case PARTCODE_XY2:
- return from_obj.get_part(X) + from_obj.get_part(W);
- case PARTCODE_WH:
- return from_obj.get_part(W);
- case PARTCODE_CENTER:
- return from_obj.get_part(X) + (from_obj.get_part(W)/2);
- case PARTCODE_VISIBLE:
- return from_obj.get_part(VISIBLE);
- case PARTCODE_ENABLED:
- return from_obj.get_part(ENABLED);
- case PARTCODE_PART_A:
- return from_obj.get_part(PART_A);
- case PARTCODE_PART_B:
- return from_obj.get_part(PART_B);
- default:
- throw new sub_arctic_error("Bad part code ("+ from_part +
- ") in get_value()");
- }
- else
- /* vertical */
- switch (from_part)
- {
- case PARTCODE_XY:
- return from_obj.get_part(Y);
- case PARTCODE_XY2:
- return from_obj.get_part(Y) + from_obj.get_part(H);
- case PARTCODE_WH:
- return from_obj.get_part(H);
- case PARTCODE_CENTER:
- return from_obj.get_part(Y) + (from_obj.get_part(H)/2);
- case PARTCODE_VISIBLE:
- return from_obj.get_part(VISIBLE);
- case PARTCODE_ENABLED:
- return from_obj.get_part(ENABLED);
- case PARTCODE_PART_A:
- return from_obj.get_part(PART_A);
- case PARTCODE_PART_B:
- return from_obj.get_part(PART_B);
- default:
- throw new sub_arctic_error("Bad part code ("+ from_part +
- ") in get_value()");
- }
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /** Fetch a particular value from a parent object on behalf of a given part
- * in a particular orientation. This is used for parent values only. It
- * applied coordinate transform for position values to place them in
- * the local coordinates of the "from_obj" (which is the parent)<p>
- *
- * @see std_constraint_impl#get_parent_value
- * @param interactor from_obj object we are getting the value from
- * @param int from_part component of that object we want
- * @param int orient orientation (should be HORIZONTAL or VERTICAL)
- * @returns int the value requested (brought up-to-date if needed)
- */
- protected int get_parent_value(
- interactor from_obj,
- int from_part,
- int orient)
- {
- /* horizontal? */
- if (orient == HORIZONTAL)
- switch (from_part)
- {
- case PARTCODE_XY:
- return from_obj.x_into_local(from_obj.get_part(X));
- case PARTCODE_XY2:
- return from_obj.x_into_local(from_obj.get_part(X)) +
- from_obj.get_part(W);
- case PARTCODE_WH:
- return from_obj.get_part(W);
- case PARTCODE_CENTER:
- return from_obj.x_into_local(from_obj.get_part(X)) +
- (from_obj.get_part(W)/2);
- case PARTCODE_VISIBLE:
- return from_obj.get_part(VISIBLE);
- case PARTCODE_ENABLED:
- return from_obj.get_part(ENABLED);
- case PARTCODE_PART_A:
- return from_obj.get_part(PART_A);
- case PARTCODE_PART_B:
- return from_obj.get_part(PART_B);
- default:
- throw new sub_arctic_error("Bad part code in get_value()");
- }
- else
- /* vertical */
- switch (from_part)
- {
- case PARTCODE_XY:
- return from_obj.y_into_local(from_obj.get_part(Y));
- case PARTCODE_XY2:
- return from_obj.y_into_local(from_obj.get_part(Y)) +
- from_obj.get_part(H);
- case PARTCODE_WH:
- return from_obj.get_part(H);
- case PARTCODE_CENTER:
- return from_obj.y_into_local(from_obj.get_part(Y)) +
- (from_obj.get_part(H)/2);
- case PARTCODE_VISIBLE:
- return from_obj.get_part(VISIBLE);
- case PARTCODE_ENABLED:
- return from_obj.get_part(ENABLED);
- case PARTCODE_PART_A:
- return from_obj.get_part(PART_A);
- case PARTCODE_PART_B:
- return from_obj.get_part(PART_B);
- default:
- throw new sub_arctic_error("Bad part code in get_value()");
- }
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * Fetch the indicated depended-upon value for the given object and part.<p>
- *
- * @param int objpart_code encoding of object/part we need to fetch
- * @param interactor constr_obj constrained object we are fetching value
- * for. fetched values are found relative to
- * this object.
- * @param int orient orientation of fetched value (should be
- * HORIZONTAL or VERTICAL).
- * @return int fetched value (brought up to date if necessary
- */
- public int fetch_value(
- int objpart_code,
- interactor constr_obj,
- int orient)
- {
- int depend_on_obj;
- int depend_on_part;
- int cnt, i, v;
- int value = 0;
- interactor target = null;
-
- /* Sanity check */
- if (constr_obj == null)
- throw new sub_arctic_error("Null constrained object passed to fetch_value()");
-
- /* extract the object and part from the encoding */
- depend_on_obj = std_objpart_encoding.object_encoded(objpart_code);
- depend_on_part = std_objpart_encoding.part_encoded(objpart_code);
-
- /* get the value we depend on */
- switch (depend_on_obj)
- {
- case OBJCODE_SELF:
- return get_value(constr_obj, depend_on_part, orient);
-
- /* . . . . . . . . . . */
-
- case OBJCODE_PARENT:
- /* get the parent -- if its null we return 0 */
- target = constr_obj.parent();
- if (target == null) return 0;
-
- /* if we are asking for X or Y they are always 0 for parent */
- if (depend_on_part == PARTCODE_XY)
- return 0;
- else
- /* get the value from the parent */
- return get_parent_value(target,depend_on_part,orient);
-
- /* . . . . . . . . . . */
-
- case OBJCODE_FIRST_CHILD:
- if (constr_obj.num_children() > 0)
- {
- /* get the first child */
- target = constr_obj.child(0);
- /* if it really exists, get the value */
- if (target != null)
- return get_value(target, depend_on_part, orient);
- }
- /* there are no children, or child is missing, return 0 */
- return 0;
-
- case OBJCODE_LAST_CHILD:
- if (constr_obj.num_children() > 0)
- {
- /* get the first child */
- target = constr_obj.child(constr_obj.num_children()-1);
- /* if it really exists, get the value */
- if (target != null)
- return get_value(target, depend_on_part, orient);
- }
- /* there are no children, or child is missing, return 0 */
- return 0;
-
- case OBJCODE_MAX_CHILD:
- /* walk down children of constrained object and compute max */
- value = Integer.MIN_VALUE;
- cnt = 0;
- for (i = 0; i < constr_obj.num_children(); i++)
- {
- /* extract the child and see if its real */
- target = constr_obj.child(i);
- if (target != null)
- {
- /* count it and get the value in question */
- cnt++;
- v = get_value(target, depend_on_part, orient);
-
- /* compute max */
- if (v > value) value = v;
- }
- }
-
- /* treat zero children special */
- if (cnt == 0) value = 0;
-
- return value;
-
- case OBJCODE_MIN_CHILD:
- /* walk down children of constrained object and compute min */
- value = Integer.MAX_VALUE;
- cnt = 0;
- for (i = 0; i < constr_obj.num_children(); i++)
- {
- /* extract the child and see if its real */
- target = constr_obj.child(i);
- if (target != null)
- {
- /* count it and get the value in question */
- cnt++;
- v = get_value(target, depend_on_part, orient);
-
- /* compute min */
- if (v < value) value = v;
- }
- }
-
- /* treat zero children special */
- if (cnt == 0) value = 0;
-
- return value;
-
- case OBJCODE_PREV_SIBLING:
- /* get the sibling */
- target = constr_obj.prev_sibling();
-
- /* if no sibling substitute zero */
- if (target == null) return 0;
-
- /* otherwise get the value */
- return get_value(target, depend_on_part, orient);
-
- case OBJCODE_NEXT_SIBLING:
- /* get the sibling */
- target = constr_obj.next_sibling();
-
- /* if its null supply edge of parent or zero */
- if (target == null)
- {
- switch(depend_on_part)
- {
- /* parent w/h substitutes for missing sibling edge */
- case PARTCODE_XY:
- case PARTCODE_XY2:
- target = constr_obj.parent();
-
- /* if there is no parent return 0 */
- if (target == null) return 0;
-
- /* otherwise use its wh */
- return get_value(target, PARTCODE_WH, orient);
-
- /* other cases go to zero */
- default: return 0;
- }
- }
- else
- /* return the normal value */
- return get_value(target, depend_on_part, orient);
-
- default:
- throw new sub_arctic_error("Bad object code " + depend_on_obj +
- " passed to fetch_value()");
- }
- }
-
- //had:
- //* @exception bad_value if a bad obj/part code or constrained object are
- //* passed.
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * Determine if a given constraint encoding represents "none" (i.e., that
- * no constraint is to be applied).<p>
- *
- * @param int enc the encoding for the constraint.
- * @return boolean whether the encoding indicates "none".
- */
- public boolean is_none(int enc)
- {
- return (enc & NONE_TEST_MASK) == NONE_TEST_VAL;
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * Determine if a given constraint encoding represents an external
- * constraint.<p>
- *
- * @param int enc the encoding for the constraint.
- * @param boolean whether the encoding indicates an external constraint.
- */
- public boolean is_external(int enc)
- {
- return (enc & EXTERNAL_TEST_MASK) == EXTERNAL_TEST_VAL;
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * Evaluate an encoded constraint (under a given orientation). The
- * constraint is being applied to the given part of the given object (i.e.
- * the constr_part part of the constr_obj object). The encoding typically
- * will designate parameter values relative to that object (i.e. the width
- * of the parent of the object). <p>
- *
- * @param int enc the encoding of the constraint
- * @param interactor constr_obj the object being constrained
- * @param int constr_part the part being constrained
- * @param int orient the orientation of the constraint
- * @return int the result of the evaluation
- */
- public int eval(
- int enc,
- interactor constr_obj,
- int constr_part,
- int orient)
- {
- /* bail out early with same value if the constraint is "none". */
- if (is_none(enc)) return constr_obj.get_part(constr_part);
-
- /* send work to one of the classes for different numbers of operands */
- switch(num_ops(enc))
- {
- case 0: return op0_impl.eval(enc, constr_obj, constr_part,orient);
- case 1: return op1_impl.eval(enc, constr_obj, constr_part,orient);
- case 2: return op2_impl.eval(enc, constr_obj, constr_part,orient);
- case 3: return op3_impl.eval(enc, constr_obj, constr_part,orient);
- default: throw new sub_arctic_error("Unrecognized constraint encoding " +
- "passed to std_constraint_impl.eval()");
- }
- }
-
- //had:
- //* @exception bad_value if the encoding, or constrained object/part are
- //* malformed
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /** Test whether the given encoded constraint depends on the indicated
- * neighboring object and part. The constraint is attached to the
- * constr_obj object and this test is expressed relative to that object.
- * The object and part that we determining dependency upon is encoded in
- * test_which_obj and test_which_part. For tests of child objects, an
- * indication of the index of that child is also given.<p>
- *
- * If this is an "external" constraint that maintains its own dependency
- * edges and works through the external notification system, then this
- * method may safely return false in all cases.<p>
- *
- * @param int enc The encoding for the constraint.
- * @param interactor constr_obj The object the constraint is attached to
- * @param int test_which_obj The neighboring object we are asking
- * about. This can be one of the values
- * OBJCODE_SELF, OBJCODE_PARENT,
- * OBJCODE_SOME_CHILD,
- * OBJCODE_PREV_SIBLING, or
- * OBJCODE_NEXT_SIBLING.
- * @param int test_which_part The part we are asking about.
- * @param int nth_child for SOME_CHILD, this provides the index
- * of the child (and is ignored otherwise).
- * @param int orient Orientation of the constraint. This
- * should be HORIZONTAL or VERTICAL.
- * @return boolean whether the given constraint depends upon the given value
- */
- public boolean depends_on(
- int enc,
- interactor constr_obj,
- int which_obj,
- int which_part,
- int nth_child,
- int orient)
- {
- /* bail out early with same value if the constraint is "none". */
- if (is_none(enc)) return false;
-
- /* send work to one of the classes for different numbers of operands */
- switch(num_ops(enc))
- {
- case 0:
- return op0_impl.depends_on(enc, constr_obj, which_obj,
- which_part, nth_child, orient);
- case 1: return op1_impl.depends_on(enc, constr_obj, which_obj,
- which_part, nth_child, orient);
- case 2: return op2_impl.depends_on(enc, constr_obj, which_obj,
- which_part, nth_child, orient);
- case 3: return op3_impl.depends_on(enc, constr_obj, which_obj,
- which_part, nth_child, orient);
- default: throw new sub_arctic_error("Unrecognized constraint encoding " +
- "passed to std_constraint_impl.depends_on()");
- }
- }
-
- //had:
- //* @exception bad_value if one of the parameters has an unrecognized value
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /** Test whether the given encoded object/part indicates the given
- * object and part for dependency purposes. For example,
- * part_depends_on(enc, cobj, OBJCODE_PARENT, PARTCODE_W, 0, HORIZONTAL)
- * would test if the object/part encoded in enc and part of the constraint
- * attached to cobj indicates a dependency on the width of the parent of
- * cobj.
- *
- * @param int enc The encoding we are testing.
- * @param interactor constr_obj The object the constraint is attached to
- * @param int test_which_obj The object we are asking about. This
- * can be one of the values OBJCODE_SELF,
- * OBJCODE_PARENT, OBJCODE_SOME_CHILD,
- * OBJCODE_PREV_SIBLING, or
- * OBJCODE_NEXT_SIBLING.
- * @param int test_which_part The part we are asking about.
- * @param int nth_child for SOME_CHILD, this provides the index
- * of the child (and is ignored otherwise).
- * @param int orient Orientation of the constraint. This
- * should be HORIZONTAL or VERTICAL.
- * @return boolean whether the given constraint depends upon the given value
- */
- public boolean part_depends_on(
- int enc,
- interactor constr_obj,
- int which_obj,
- int which_part,
- int nth_child,
- int orient)
- {
- int d_obj, d_part, n_child;
-
- /* pull out the encoded object */
- d_obj = (enc >> OBJCODE_SHIFT) & OBJCODE_MASK;
-
- /* if they are not talking about the same object we fail */
- switch(which_obj)
- {
- case OBJCODE_SELF:
- if (d_obj != OBJCODE_SELF) return false;
- break;
-
- case OBJCODE_PARENT:
- if (d_obj != OBJCODE_PARENT)
- {
- /* next sibling falls back on parent if there is none */
- if (d_obj == OBJCODE_NEXT_SIBLING &&
- constr_obj.next_sibling() == null)
- {
- /* but only on xy and xy2 */
- d_part = (enc >> PARTCODE_SHIFT) & PARTCODE_MASK;
- return d_part == PARTCODE_XY || d_part == PARTCODE_XY2;
- }
- /* not the special case and doesn't match parent */
- return false;
- }
- break;
-
- case OBJCODE_PREV_SIBLING:
- if (d_obj != OBJCODE_PREV_SIBLING) return false;
- break;
-
- case OBJCODE_NEXT_SIBLING:
- if (d_obj != OBJCODE_NEXT_SIBLING) return false;
- break;
-
- case OBJCODE_SOME_CHILD:
- /* max/min child depend on any/all children */
- if (d_obj != OBJCODE_MAX_CHILD && d_obj != OBJCODE_MIN_CHILD)
- {
- /* see if we match as first or last child */
- n_child = constr_obj.num_children();
- if (!(d_obj==OBJCODE_FIRST_CHILD && n_child>0&&nth_child==0)&&
- !(d_obj==OBJCODE_LAST_CHILD && nth_child == n_child-1))
- return false;
- }
- break;
-
- default:
- throw new sub_arctic_error("Unknown object kind passed to " +
- "std_constraint_impl.part_depends_on()");
- }
-
- /* if we make it here, then we have determined that we are talking
- * about the same object. Now we look at the part code. */
- d_part = (enc >> PARTCODE_SHIFT) & PARTCODE_MASK;
- if (orient == HORIZONTAL)
- switch(which_part)
- {
- case X: return d_part == PARTCODE_XY ||
- d_part == PARTCODE_XY2 ||
- d_part == PARTCODE_CENTER;
- case W: return d_part == PARTCODE_WH ||
- d_part == PARTCODE_XY2 ||
- d_part == PARTCODE_CENTER;
- case VISIBLE: return d_part == PARTCODE_VISIBLE;
- case ENABLED: return d_part == PARTCODE_ENABLED;
- case PART_A: return d_part == PARTCODE_PART_A;
- case PART_B: return d_part == PARTCODE_PART_B;
- default: return false;
- }
- else
- switch(which_part)
- {
- case Y: return d_part == PARTCODE_XY ||
- d_part == PARTCODE_XY2 ||
- d_part == PARTCODE_CENTER;
- case H: return d_part == PARTCODE_WH ||
- d_part == PARTCODE_XY2 ||
- d_part == PARTCODE_CENTER;
- case VISIBLE: return d_part == PARTCODE_VISIBLE;
- case ENABLED: return d_part == PARTCODE_ENABLED;
- case PART_A: return d_part == PARTCODE_PART_A;
- case PART_B: return d_part == PARTCODE_PART_B;
- default: return false;
- }
- }
-
- //had:
- //* @exception bad_value if one of the parameters has an unrecognized value
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * Extract the set of objects/parts that a constraint depends on. This
- * produces a Vector with pairs of entries, the first being an interactor,
- * and the second being an Integer which is the part number of that
- * interactor that is depended upon.<p>
- *
- * @param int enc encoding value for the constraint in question.
- * @param interactor constr_obj the object the constraint is attached to
- * (hence its referents are relative to).
- * @param int orient Orientation of the constraint. This
- * should be HORIZONTAL or VERTICAL.
- * @return Vector containing pairs of objects, the first being an interactor
- * which is depended upon, and the second being an Integer
- * giving the part number of the part depended upon.
- */
- public Vector depend_list(int enc, interactor constr_obj, int orient)
- {
- /* send work to one of the classes for different numbers of operands */
- switch(num_ops(enc))
- {
- case 0:
- return op0_impl.mk_depend_list(enc, constr_obj, orient);
- case 1:
- return op1_impl.mk_depend_list(enc, constr_obj, orient);
- case 2:
- return op2_impl.mk_depend_list(enc, constr_obj, orient);
- case 3:
- return op3_impl.mk_depend_list(enc, constr_obj, orient);
- default:
- throw new sub_arctic_error("Unrecognized constraint encoding " +
- "passed to std_constraint_impl.depend_list()");
- }
- }
-
- //had:
- //* @exception bad_value if one of the parameters is malformed.
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * Extract the dependencies that are implicit in the particular operation
- * encoded in the given standard constraint encoding. <p>
- *
- * @param int enc encoding value for the constraint in question.
- * @param interactor constr_obj the object the constraint is attached to
- * (hence its referents are relative to).
- * @param int orient Orientation of the constraint. This
- * should be HORIZONTAL or VERTICAL.
- * @return Vector containing pairs of objects, the first being an interactor
- * which is depended upon, and the second being an Integer
- * giving the part number of the part depended upon.
- */
- public Vector implicit_depend_list(int enc, interactor constr_obj, int orient)
- {
- /* send work to one of the classes for different numbers of operands */
- switch(num_ops(enc))
- {
- case 0:
- return op0_impl.mk_implicit_depend_list(enc, constr_obj, orient);
- case 1:
- return op1_impl.mk_implicit_depend_list(enc, constr_obj, orient);
- case 2:
- return op2_impl.mk_implicit_depend_list(enc, constr_obj, orient);
- case 3:
- return op3_impl.mk_implicit_depend_list(enc, constr_obj, orient);
- default:
- throw new sub_arctic_error("Unrecognized constraint encoding " +
- "passed to std_constraint_impl.implicit_depend_list()");
- }
- }
-
- //had:
- //* @exception bad_value if the encoding value is not valid.
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * Extract a depended upon object/part from the given object/part encoding
- * and add it to the end of the given vector. This is used by depend_list()
- * to produce parts of its result. Appended to the Vector will be two values,
- * an interactor which is the object depended upon, and an Integer with the
- * part number within that object that is depended upon.<p>
- *
- * @param Vector result the Vector object we add to the end of.
- * @param int part_enc encoding value for object/part in question.
- * @param interactor constr_obj the object the constraint is attached to
- * (hence its referents are relative to).
- * @param int orient Orientation of the constraint. This
- * should be HORIZONTAL or VERTICAL.
- */
- protected void add_depend_obj_part(
- Vector result,
- int part_enc,
- interactor constr_obj,
- int orient)
- {
- int d_obj, d_part, i;
-
- /* pull out the encoded object and part */
- d_obj = (part_enc >> OBJCODE_SHIFT) & OBJCODE_MASK;
- d_part = (part_enc >> PARTCODE_SHIFT) & PARTCODE_MASK;
-
- /* append interactor corresponding to encoded object */
- switch(d_obj)
- {
- case OBJCODE_SELF:
- result.addElement(constr_obj);
- break;
-
- case OBJCODE_PARENT:
- if (constr_obj.parent() == null) return;
- result.addElement(constr_obj.parent());
- break;
-
- case OBJCODE_PREV_SIBLING:
- if (constr_obj.prev_sibling() == null) return;
- result.addElement(constr_obj.prev_sibling());
- break;
-
- case OBJCODE_NEXT_SIBLING:
- if (constr_obj.next_sibling() != null)
- result.addElement(constr_obj.next_sibling());
- else
- {
- /* special case for next_sibling fallback to parent */
- if (constr_obj.parent() == null) return;
-
- /* but only for XY or XY2 */
- if (d_part != PARTCODE_XY && d_part != PARTCODE_XY2) return;
-
- /* fallback to parent.xy2 */
- result.addElement(constr_obj.parent());
- d_part = PARTCODE_XY2;
- }
- break;
-
- case OBJCODE_FIRST_CHILD:
- if (constr_obj.num_children() >= 1)
- result.addElement(constr_obj.child(0));
- else
- return;
- break;
-
- case OBJCODE_LAST_CHILD:
- if (constr_obj.num_children() >= 1)
- result.addElement(
- constr_obj.child(constr_obj.
- num_children()-1));
- else
- return;
- break;
-
- case OBJCODE_MAX_CHILD:
- case OBJCODE_MIN_CHILD:
- /* we are dependent on every child */
- for (i = 0; i < constr_obj.num_children(); i++)
- {
- /* add the child and the part */
- result.addElement(constr_obj.child(i));
- add_depend_part(result, d_part, orient);
- }
- return;
-
- default:
- throw new sub_arctic_error("Unknown object kind passed to " +
- "std_constraint_impl.part_depends_on()");
- }
-
- /* now do the part */
- add_depend_part(result, d_part, orient);
- }
-
- //had:
- //* @exception bad_value if one of the parameters is malformed.
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * Append depended upon part numbers to the given Vector. This assumes
- * that the last element of the vector contains the object depended on.
- * If the part encoding given requires multiple dependencies additional
- * dependent object values will be added so that we always have object/part
- * pairs.<p>
- *
- * @param Vector result the Vector object we add to the end of.
- * @param int part_enc encoding value for part in question.
- * @param int orient Orientation of the constraint. This
- * should be HORIZONTAL or VERTICAL.
- */
- protected void add_depend_part(
- Vector result,
- int part_enc,
- int orient)
- {
- interactor dep_obj = (interactor)result.elementAt(result.size()-1);
-
- switch (part_enc)
- {
- case PARTCODE_XY:
- if (orient == HORIZONTAL)
- result.addElement(new Integer(X));
- else
- result.addElement(new Integer(Y));
- break;
-
- case PARTCODE_CENTER:
- case PARTCODE_XY2:
- if (orient == HORIZONTAL)
- {
- result.addElement(new Integer(X));
- result.addElement(dep_obj);
- result.addElement(new Integer(W));
- }
- else
- {
- result.addElement(new Integer(Y));
- result.addElement(dep_obj);
- result.addElement(new Integer(H));
- }
- break;
-
- case PARTCODE_WH:
- if (orient == HORIZONTAL)
- result.addElement(new Integer(W));
- else
- result.addElement(new Integer(H));
- break;
-
- case PARTCODE_VISIBLE:
- result.addElement(new Integer(VISIBLE));
- break;
-
- case PARTCODE_ENABLED:
- result.addElement(new Integer(ENABLED));
- break;
-
- case PARTCODE_PART_A:
- result.addElement(new Integer(PART_A));
- break;
- case PARTCODE_PART_B:
- result.addElement(new Integer(PART_B));
- break;
- }
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
- }
-
- /*=========================== COPYRIGHT NOTICE ===========================
-
- This file is part of the subArctic user interface toolkit.
-
- Copyright (c) 1996 Scott Hudson and Ian Smith
- All rights reserved.
-
- The subArctic system is freely available for most uses under the terms
- and conditions described in
- http://www.cc.gatech.edu/gvu/ui/sub_arctic/sub_arctic/doc/usage.html
- and appearing in full in the lib/interactor.java source file.
-
- The current release and additional information about this software can be
- found starting at: http://www.cc.gatech.edu/gvu/ui/sub_arctic/
-
- ========================================================================*/
-